import os
from os.path import join

def walk(root_dir, file_filter, action):
    for dirpath, dirnames, filenames in os.walk(root_dir):
        for filename in filenames:
            if file_filter(filename):
                path = join(dirpath, filename)
                f = open(path, 'r')
                action(path, f.read())
                f.close()

def find_classes(root_dir, file_filter, class_filter):
    classes = set()
    from src.info_extractor import InfoExtractor
    e = InfoExtractor()
    walk(root_dir, file_filter, lambda path, c: classes.update(e.process(c)))
    return set([c for c in classes if class_filter(c)])

def find_occurrences(root_dir, file_filter, classes):
    occurrences = dict()
    from src.match_finder import MatchFinder
    f = MatchFinder(classes)
    walk(root_dir, file_filter, lambda path, content: occurrences.update(f.process(content)))
    return occurrences

def run(root_dir, 
        test_file,
        definition_filter=lambda f: f.endswith('.h'), 
        occurrences_filter= lambda f: f.endswith('.h') or f.endswith('.cpp'), 
        class_filter=lambda c: True):
    from src.test_builder import TestBuilder
    b = TestBuilder(test_file)
    classes = find_classes(root_dir, definition_filter, class_filter)
    occurrences = find_occurrences(root_dir, occurrences_filter, classes)
    for klass, occurrences_list in occurrences.iteritems():
        for occurrence in occurrences_list:
            b.add_ocurrence(occurrence)
    for klass in classes:
        if klass not in occurrences.keys():
            b.add_class(klass)
    b.save()

run('/home/hugo/fuentes/fudepan-build/projects/biopp', "example_test.cpp")
